package dcsinstnce.server.topic.impl;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

import javax.swing.tree.DefaultMutableTreeNode;

import org.omg.CORBA.Object;

import dcsinstnce.pds.uchiha.corba.manager.CorbaManager;
import dcsinstnce.server.accessers.impl.DataReaderImpl;
import dcsinstnce.server.datas.DataObject;
import dcsinstnce.server.domaines.impl.LocalDomaineManagerImpl;
import dcsinstnce.server.interfaces.Suscriber;
import dcsinstnce.server.interfaces.SuscriberHelper;
import dcsinstnce.server.interfaces.SuscriberPOATie;
import dcsinstnce.server.interfaces.impl.SuscriberImpl;
import dcsinstnce.server.lifecyclemanager.CacheLifeCycleManagerListenerImpl;
import dcsinstnce.server.topic.TopicOperations;

public class TopicImpl implements TopicOperations{
	private Hashtable<String, TopicImpl> topics;
	private DataObject data;
	private String name;
	private String fullName;
	private SuscriberImpl suscriber;
	private DataReaderImpl dataReader;
	private CacheLifeCycleManagerListenerImpl cachelifecycle;
	private static int ic = 0;
	
	private LocalDomaineManagerImpl domaine;
	
	public void setDomaine(LocalDomaineManagerImpl domaine) {
		this.domaine = domaine;
		cachelifecycle = CacheLifeCycleManagerListenerImpl.getInstance();
	}
	// TODO Auto-generated method stub

	public void setsuscriber(SuscriberImpl suscriber) {
		this.suscriber = suscriber;
	}
	/**
	 * constructeur
	 * @param name : nom
	 * @param parent : son parent
	 */
	public TopicImpl(String name, String parent) {
		ic++;
		this.name = name;
		if(parent.equals(""))
			this.fullName = name;
		else
			this.fullName = parent + "." + name;
		this.dataReader = new DataReaderImpl(this);
		topics = new Hashtable<String, TopicImpl>();
	}
	
	/**
	 * 
	 * @return : datareader du topic
	 */
	public DataReaderImpl getDataReader(){
		return this.dataReader;
	}
	/**
	 * 
	 * @return
	 */
	public DefaultMutableTreeNode createNode(){
		DefaultMutableTreeNode node = new DefaultMutableTreeNode(name);
		Set<String> keys = topics.keySet();
		Iterator<String> strings = keys.iterator();
		while(strings.hasNext()){
			String x = strings.next();
			DefaultMutableTreeNode node1 = topics.get(x).createNode();
			node.add(node1);
		}
		return node;
	}

	@Override
	public DataObject getDataObject() {
		return data;
	}

	@Override
	public String getName() {
		return name;
	}
	/**
	 * 
	 * @param topicName : nom du topic a rechercher
	 * @return : subscriber correspondant au topic
	 */
	public Suscriber getSuscriberWithPath(String topicName){
		int x = topicName.indexOf(".");
		if(x < 0){
			TopicImpl topic = topics.get(topicName);
			if(topic == null)
				return null;
			return topic.getSuscriber();
		}
		String topicN = topicName.substring(0, x);
		TopicImpl topic = topics.get(topicN);
		if(topic == null)
			return null;
		return topic.getSuscriberWithPath(topicName.substring(x + 1, topicName.length()));
	}

	@Override
	public Suscriber getSuscriber() {
		SuscriberPOATie suscriber = new SuscriberPOATie(this.suscriber);
		Object obj = CorbaManager.getInstance().publish(suscriber, "suscriber " + ic);
		return SuscriberHelper.narrow(obj);
	}

	@Override
	public boolean createTopic(String topicName) {
		TopicImpl topic = new TopicImpl(topicName, fullName);
		topic.setDomaine(domaine);
		topic.setsuscriber((SuscriberImpl)domaine.getSuscriberManager().addNewDataReaderListener(
				topic.getFullName(),
				topic.getDataReader())
			);
		boolean res = topics.put(topicName, topic) != null;
		if(domaine != null)
			domaine.showFrame();
		cachelifecycle.notifyCacheCreation(this, "");
		return res;
	}

	@Override
	public boolean deleteTopic(String topicName) {
		boolean res = topics.remove(topicName) != null;
		if(domaine != null)
			domaine.showFrame();
		cachelifecycle.notifyCacheDelete(this, "");
		return res;
	}

	@Override
	public boolean createCache() {
		data = new DataObject();
		return data != null;
	}

	@Override
	public boolean deleteCache() {
		data = null;
		return data == null;
	}
	@Override
	public String toString() {
		return name;
	}
	/**
	 * 
	 * @return : nom absolu du topic
	 */
	public String getFullName() {
		return fullName;
	}
}
